/*
 * =====================================================================================
 *
 *       Filename:  genCharacters.cpp
 *
 *    Description:  First mock-up version of generating chars using SA
 *
 *        Version:  1.0
 *        Created:  16/07/12 15:42:01
 *       Revision:  none
 *       Compiler:  gcc
 *
 *         Author:  Moos Hueting (mh), mooshueting@gmail.com
 *   Organization:  
 *
 * =====================================================================================
 */
#include <iostream>
#include <stdlib.h>
#include "sa.h"
#include "features/char_features.h"

#define N_RUNS 3000

using namespace std;
using namespace cv;

Mat crop(Mat src) {
         if (countNonZero(src) == 0)
             return src;
         Mat tmp(src);
 
         Size s = src.size();
 
         int minx = 1000;
         int maxx = 0;
         int miny = 1000;
         int maxy = 0;
 
         for (int i = 0; i < s.height; i++) {
             for (int j = 0; j < s.width; j++) {
                 //if the current pixel is set
                 if (src.at<float>(i, j) > 0) { 
                     if (i < miny)
                         miny = i;
                     if (i > maxy)
                         maxy = i;
                     if (j < minx)
                         minx = j;
                     if (j > maxx)
                         maxx = j;
                 }
             }
         }
 
         return src(Range(miny, maxy), Range(minx, maxx));
//         int dy = ((s.height - maxy) - miny) / 2;
//         int dx = ((s.width - maxx) - minx) / 2;
//         cout << dy << ", " << dx << endl;
// 
//         s = src.size();
// 
//         if (dx != 0) {
//             // up or down?
//             if (dx < 0) {
//                 cout << "NEGATIVE" << endl;
//                 dx *= -1;
//                 Mat tmp1 = tmp(Rect(0,0,s.width - dx, s.height));
//                 src(Rect(dx,0,s.width-dx,s.height)).copyTo(tmp1);
// 
//                 Mat tmp2 = tmp(Rect(s.width-dx,0,dx,s.height));
//                 src(Rect(0,0,dx,s.height)).copyTo(tmp2);
//             } else {
//                 cout << "POSITIVE" << endl;
//                 Mat tmp1 = tmp(Rect(dx,0,s.width-dx,s.height));
//                 src(Rect(0,0,s.width-dx,s.height)).copyTo(tmp1);
// 
//                 Mat tmp2 = tmp(Rect(0,0,dx,s.height));
//                 src(Rect(s.width-dx,0,dx,s.height)).copyTo(tmp2);
//             }
//         }
///*          if (dx != 0) {
// *              // left or right?
// *              if (dx < 0) {
// *                  dx *= -1;
// *                  Mat tmp1 = tmp(Rect(0,0,s.height,s.width-dx));
// *                  src(Rect(0,dx,s.height,s.width-dx)).copyTo(tmp1);
// *                  Mat tmp2 = tmp(Rect(0,s.width-dx,s.height,dx));
// *                  src(Rect(0,0,s.height,dx)).copyTo(tmp2);
// *              } else {
// *                  Mat tmp1 = tmp(Rect(0,dx,s.height,s.width-dx));
// *                  src(Rect(0,0,s.height,s.width-dx)).copyTo(tmp1);
// *                  Mat tmp2 = tmp(Rect(0,0,s.height,dx));
// *                  src(Rect(0,s.width-dx,s.height,dx)).copyTo(tmp2);
// *              }
// *          }
// */
// 
//         return tmp;
}

void printStatus(int i, int j, int m, int n) {
    printf("Generating character %d out of %d [", i+1, m);
    for (int c = 0; c <= (j*20)/n; c++)
        cout << ".";
    for (int c = (j*20)/n + 1; c < 20; c++)
        cout << " ";
    printf("]\r");
}

int main(int argc, char* argv[]) {

    int n = atoi(argv[2]);

    for (int i=0; i < n; i++) {
        char filename[40];
        sprintf(filename, "%s/%02d.png", argv[1], i);
        SA sa(argv[3]);
        Mat disp;


        printStatus(i, 0, n, N_RUNS);

        for (int j = 0; j < N_RUNS; j++) {
            if (sa.energy() > -1e+11)
                sa.lowerTemperature();
            sa.step();
            printStatus(i, j, n, N_RUNS);

        }

        cout << "GET HERE" << endl;
        Mat fin = sa.getSolution();
        fin = isocontour(fin);
        fin *= 255;

        Mat strel = getStructuringElement(MORPH_ELLIPSE, Size(3,3));

        dilate(fin, fin, strel, Point(-1,-1), 2);

        //fin = crop(fin);

        imwrite(filename, fin);
        cout << endl;
    }
    
}
